<template>
  <Form
    ref="schemaFormRef"
    v-bind="pick(getFormProps, aFormPropKeys)"
    :model="formModel"
    @keypress.enter="handleEnterPress"
  >
    <Row v-bind="getRowConfig">
      <slot name="formHeader"></slot>
      <slot>
        <template v-for="schemaItem in formSchemasRef" :key="schemaItem.field">
          <SchemaFormItem v-model:form-model="formModel" :schema="schemaItem">
            <template v-for="item in Object.keys($slots)" #[item]="data" :key="item">
              <slot :name="item" v-bind="data || {}"></slot>
            </template>
          </SchemaFormItem>
        </template>
        <FormAction
          v-if="showActionButtonGroup"
          v-bind="getFormActionBindProps"
          @toggle-advanced="handleToggleAdvanced"
        >
          <template v-for="item in ['resetBefore', 'submitBefore', 'advanceBefore', 'advanceAfter']" #[item]="data">
            <slot :name="item" v-bind="data || {}"></slot>
          </template>
        </FormAction>
      </slot>
      <slot name="formFooter"></slot>
    </Row>
  </Form>
</template>

<script lang="ts" setup name="SchemaForm">
import { useAttrs, onMounted } from 'vue';
import { pick } from 'lodash';
import { Form, Row } from 'ant-design-vue';
import SchemaFormItem from './SchemaFormItem.vue';
import FormAction from './components/FormAction.vue';
import {
  createFormContext,
  useFormState,
  useFormEvents,
  useFormMethods,
  useAdvanced,
  type SchemaFormType,
} from './hooks/';
import { schemaFormProps, schemaFormEmits, aFormPropKeys } from './SchemaForm';
import { useLocale } from '@/locales/useLocale';
import { isFunction } from '@/utils/is';
import { useI18n } from '@/hooks/useI18n';
const { getLocale } = useLocale();
const props = defineProps(schemaFormProps);
const emit = defineEmits(schemaFormEmits);
const attrs = useAttrs();

const { t } = useI18n();

const newProps = computed(() => {
  let schemas = isFunction(props.schemas) ? props?.schemas?.(t) : props.schemas;
  let oldSchemas = isFunction(props.schemas) ? props?.schemas : null; // 这个是当传的是个schema方法的时候  保存方法不需要解析 解析之后的数据就是当前的语言 切换语言之后不会在解析 所以需要保存此方法  下次调用的时候  在把语言出给此方法

  return {
    ...props,
    schemas,
    oldSchemas,
  };
});
// 表单内部状态
const formState = useFormState({ props: newProps.value, attrs });
const {
  formModel,
  getRowConfig,
  schemaFormRef,
  getFormProps,
  showActionButtonGroup,
  getFormActionBindProps,
  formSchemasRef,
  formPropsRef,
} = formState;

// 表单内部方法
const formMethods = useFormMethods({ ...formState });
const { handleFormValues } = formMethods;

// a-form表单事件二次封装和扩展
const formEvents = useFormEvents({ ...formState, emit, handleFormValues });
const { handleEnterPress, setDefaultValue } = formEvents;

// 当前组件所有的状态和方法
const instance = {
  ...formState,
  ...formEvents,
  ...formMethods,
} as SchemaFormType;

// 搜索表单 展开/收起 表单项hooks
const { handleToggleAdvanced } = useAdvanced({
  instance,
  emit,
});
emit('register', instance);

createFormContext(instance);

defineExpose(instance);

onMounted(() => {
  // 初始化表单默认值
  setDefaultValue(formSchemasRef.value);
});

watch(
  () => getLocale.value,
  (value, oldVal) => {
    let oldSchema = formPropsRef.value.oldSchemas;

    if (formSchemasRef.value && value !== oldVal) {
      instance?.clearValidate();
      if (oldSchema && isFunction(oldSchema)) {
        instance.resetSchema(oldSchema);
      } else if (formSchemasRef.value && formSchemasRef.value?.length) {
        instance.resetSchema(formSchemasRef.value);
      }
    }
  },
  {
    immediate: true,
  },
);
</script>
